package org.hawk.gwt.ppc.reflect;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

import org.hawk.gwt.ppc.Configuration;
import org.hawk.gwt.ppc.GWTModule;
import org.hawk.gwt.ppc.javacc.JavaParserTreeConstants;
import org.hawk.gwt.ppc.javacc.JavaScanner;
import org.hawk.gwt.ppc.scanner.ProcessingUnit;
import org.hawk.gwt.ppc.scanner.Processor;
import org.hawk.gwt.ppc.scanner.Token;
import org.hawk.gwt.ppc.scanner.TokenChain;
import org.hawk.gwt.ppc.utils.IO;
/**
 * Represents simple preprocessor to replace the package declaration for 
 * <code>org.hawk.gwt.ppc.reflect.emul.java.lang</code> package classes.
 * This was done retain the ability to run simple JUnit tests on java code.
 * @author alex.bereznevatiy@gmail.com
 */
public class LangPreprocessor implements ProcessingUnit, Processor {
	private static final String PACKAGE = "org.hawk.gwt.ppc.reflect";
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.Preprocessor#configure(org.hawk.gwt.ppc.Configuration, org.hawk.gwt.ppc.javacc.JavaScanner)
	 */
	public void configure(Configuration config, JavaScanner scanner) {
		scanner.addProcessor(JavaParserTreeConstants.JJTPACKAGEDECLARATION,this);
		scanner.addProcessor(JavaParserTreeConstants.JJTIMPORTDECLARATION,this);
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.Preprocessor#processModule(org.hawk.gwt.ppc.GWTModule)
	 */
	public void processModule(GWTModule module) {}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.Preprocessor#processEntryPoint(java.lang.String, java.io.Reader, java.io.Writer)
	 */
	public void processEntryPoint(String entryPoint, Reader reader,
			Writer writer) throws IOException {
		IO.flow(reader, writer);
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.Preprocessor#acceptResource(java.lang.String)
	 */
	public boolean acceptResource(String resource) {
		return resource.startsWith(PACKAGE);
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.Processor#visitStart(org.hawk.gwt.ppc.scanner.TokenChain, int)
	 */
	public void visitStart(TokenChain<? extends Token> iterator, int kind) {}

	public void visitEnd(TokenChain<? extends Token> iterator, int kind) {
		if(kind==JavaParserTreeConstants.JJTPACKAGEDECLARATION||
				kind==JavaParserTreeConstants.JJTIMPORTDECLARATION){
			boolean removeFlag = false;
			do {
				if(removeFlag){
					iterator.current().setToken("");
				}
				else if(iterator.current().getToken().equals("java")){
					removeFlag = true;
				}
				String prev = iterator.previous().getToken();
				String raw = iterator.current().getRawToken();
				if(prev.equals("package")){
					if(removeFlag)iterator.current()
						.setToken("package ");
					return;
				}
				if(prev.equals("import")){
					if(removeFlag)iterator.current()
						.setToken(raw.replace("import", "import "));
					return;
				}
			}
			while(iterator.hasPrevious());
		}
	}

}
